﻿// ______________________________________________________________
//
// Liam O'Donnell
// Basic tools I use quite a bit
// ______________________________________________________________
//

class com.spikything.utils.SpikyTools {

	// ______________________________________________________
	//
	// CONSTANTS
	// ______________________________________________________
	//

	static var RADIAN		:Number 		= 180/Math.PI;

	// ______________________________________________________
	//
	// CONSTRUCTOR
	// ______________________________________________________
	//

	function SpikyTools () {}

	// ______________________________________________________
	//
	// STATIC METHODS (grouped by type)
	// ______________________________________________________
	//

	// ***** COLOUR *****

	// Apply a simple colour transform to the given movieclip
	public static function colour (_mc:MovieClip, _ct:Object):Color {
		var c = createColour(_mc);
		c.setTransform(_ct);
		return c;
	}

	// Create and return a colour object for the given movieclip
	private static function createColour (_mc:MovieClip):Color {
		return new Color(_mc);
	}

	// Invert the RGB channels for the given movieclip
	public static function negative (_mc:MovieClip):Void {
		colour(_mc,{ra:-100, rb:255, ga:-100, gb:255, ba:-100, bb:255});
	}

	// Fade the given movieclip towards black to the given ratio (0 for black, 1 for no change)
	public static function fadeBy (_mc:MovieClip, fraction:Number):Void {
		var c = createColour(_mc).getTransform();
		colour(_mc,{ra:c.ra*fraction, ga:c.ga*fraction, ba:c.ba*fraction});
	}

	// ***** MATHS *****

	// Rotate the given movieclip to point at the given coordinate
	public static function pointAt (_mc:MovieClip, x:Number, y:Number):Void {
		_mc._rotation = getAngle(_mc._x,_mc._y,x,y);
	}

	// Get the angle between two coordinates
	public static function getAngle (x1:Number, y1:Number, x2:Number, y2:Number):Number {
		return (Math.atan2(y2-y1,x2-x1)*RADIAN)+90;
	}

	// Get the distance between two coordinates
	public static function getDist (x1:Number, y1:Number, x2:Number, y2:Number):Number {
		return Math.sqrt(getSqDist(x1,y1,x2,y2));
	}

	// Get the square of the distance between two coordinates (faster)
	public static function getSqDist (x1:Number, y1:Number, x2:Number, y2:Number):Number {
		return ((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2));
	}

	// Get the distance between two 3D point objects
	public static function getVectorLength (pt1:Object, pt2:Object):Number {
		var dx = pt1.x-pt2.x;
		var dy = pt1.x-pt2.x;
		var dz = pt1.z-pt2.z;
		return Math.sqrt((dx*dx)+(dy*dy)+(dz*dz));
	}

	// ***** MOVIECLIP *****

	// Attach  and return movie _id to _base at _customDepth with _initObject
	public static function attach (_base:MovieClip, _id:String, _initObject:Object, _customDepth:Number):MovieClip {
		if (_customDepth==undefined) var _customDepth = _base.getNextHighestDepth();
		return _base.attachMovie(_id, "m"+_customDepth, _customDepth, _initObject);
	}

	// Create and return an empty movie in _base of the given _class at _customDepth with _initObject and _args
	public static function createClass (_base:MovieClip, _class:Function, _initObject:Object, _args:Array, _customDepth:Number) {
		if (_customDepth==undefined) var _customDepth = _base.getNextHighestDepth();
		var m = _base.createEmptyMovieClip("m"+_customDepth, _customDepth);
		m.__proto__ = _class.prototype;
		for (var i in _initObject) m[i] = _initObject[i];
		_class.apply(m, _args);
		m.onLoad();
		return m;
	}

	// Attach and return movie _id in _base of the given _class at _customDepth with _initObject and _args
	public static function attachClass (_base:MovieClip, _id:String, _class:Function, _initObject:Object, _args:Array, _customDepth:Number) {
		if (_customDepth==undefined) var _customDepth = _base.getNextHighestDepth();
		var m = attach(_base, _id, _initObject, _customDepth);
		m.__proto__ = _class.prototype;
		for (var i in _initObject) m[i] = _initObject[i];
		_class.apply(m, _args);
		m.onLoad();
		return m;
	}

}